經典題目: 輸入任數字介於 1~999999999 間,並將其轉成中文樣式
ex: 100 => 壹佰
999999999 => 玖億玖仟玖佰玖拾玖萬玖仟玖佰玖拾玖
先說明我的解題思路Step 1: Function (int val)讀到的 『整數值』轉成字串
public static string GetAnswer(int val) {
if (val < 1 || val > 999999999)
return "輸入數字超出範圍 1 ~ 999,999,999";
else {
string val2str = val.ToString();
string val2ch = val2str
.Replace("0", "零").Replace("1", "壹")
.Replace("2", "貳").Replace("3", "參")
.Replace("4", "肆").Replace("5", "伍")
.Replace("6", "陸").Replace("7", "柒")
.Replace("8", "捌").Replace("9", "玖");
return val2ch;
}
}
現在已經可以取得任何數字的中文轉換
ex: GetAnswer(int 60058905) => 陸零零伍捌玖零伍
Step 2: 需要一個方法依據字串長度塞入對應的『拾』、『佰』、 ... 、『億』
static string ConvertLen2Dec(string str) {
switch (str.Length) {
case 2: return str.Substring(0, 1) + "拾" + str.Substring(1);
case 3: return str.Substring(0, 1) + "佰" + str.Substring(1, 1)
+ "拾" + str.Substring(2);
case 4: return str.Substring(0, 1) + "仟" + str.Substring(1, 1)
+ "佰" + str.Substring(2, 1)
+ "拾" + str.Substring(3);
case 5: return str.Substring(0, 1) + "萬" + str.Substring(1, 1)
+ "仟" + str.Substring(2, 1)
+ "佰" + str.Substring(3, 1)
+ "拾" + str.Substring(4);
case 6: return str.Substring(0, 1) + "拾萬" + str.Substring(1, 1)
+ "萬" + str.Substring(2, 1)
+ "仟" + str.Substring(3, 1)
+ "佰" + str.Substring(4, 1)
+ "拾" + str.Substring(5);
case 7: return str.Substring(0, 1) + "佰萬" + str.Substring(1, 1)
+ "拾萬" + str.Substring(2, 1)
+ "萬" + str.Substring(3, 1)
+ "仟" + str.Substring(4, 1)
+ "佰" + str.Substring(5, 1)
+ "拾" + str.Substring(6);
case 8: return str.Substring(0, 1) + "仟萬" + str.Substring(1, 1)
+ "佰萬" + str.Substring(2, 1)
+ "拾萬" + str.Substring(3, 1)
+ "萬" + str.Substring(4, 1)
+ "仟" + str.Substring(5, 1)
+ "佰" + str.Substring(6, 1)
+ "拾" + str.Substring(7);
case 9: return str.Substring(0, 1) + "億" + str.Substring(1, 1)
+ "仟萬" + str.Substring(2, 1)
+ "佰萬" + str.Substring(3, 1)
+ "拾萬" + str.Substring(4, 1)
+ "萬" + str.Substring(5, 1)
+ "仟" + str.Substring(6, 1)
+ "佰" + str.Substring(7, 1)
+ "拾" + str.Substring(8);
default: return "數字大於 999,999,999";
}
}
不過依照第一步的例子輸入,會得到
ex: GetAnswer(int 60058905) => 陸仟萬零佰萬零拾萬伍萬捌仟玖佰零拾伍
惱人的『零』會造成 『零佰萬』、『零拾萬』、...、『零拾』這些結果Step 3: 需要一個方法來處理『零』的問題
static string DelZero(string num, string ch) {
return num.Equals("零") ? num : num+ch;
}
// 修正後的 ConvertLen2Dec()
static string ConvertLen2Dec(string str) {
switch (str.Length) {
case 2: return str.Substring(0, 1) + "拾" + str.Substring(1);
case 3: return str.Substring(0, 1) + "佰" +
DelZero(str.Substring(1, 1), "拾") +
str.Substring(2);
case 4: return str.Substring(0, 1) + "仟" +
DelZero(str.Substring(1, 1), "佰") +
DelZero(str.Substring(2, 1), "拾") +
str.Substring(3);
case 5: return str.Substring(0, 1) + "萬" +
DelZero(str.Substring(1, 1), "仟") +
DelZero(str.Substring(2, 1), "佰") +
DelZero(str.Substring(3, 1), "拾") +
str.Substring(4);
case 6: return str.Substring(0, 1) + "拾萬" +
DelZero(str.Substring(1, 1), "萬") +
DelZero(str.Substring(2, 1), "仟") +
DelZero(str.Substring(3, 1), "佰") +
DelZero(str.Substring(4, 1), "拾") +
str.Substring(5);
case 7: return str.Substring(0, 1) + "佰萬" +
DelZero(str.Substring(1, 1), "拾萬") +
DelZero(str.Substring(2, 1), "萬") +
DelZero(str.Substring(3, 1), "仟") +
DelZero(str.Substring(4, 1), "佰") +
DelZero(str.Substring(5, 1), "拾") +
str.Substring(6);
case 8: return str.Substring(0, 1) + "仟萬" +
DelZero(str.Substring(1, 1), "佰萬") +
DelZero(str.Substring(2, 1), "拾萬") +
DelZero(str.Substring(3, 1), "萬") +
DelZero(str.Substring(4, 1), "仟") +
DelZero(str.Substring(5, 1), "佰") +
DelZero(str.Substring(6, 1), "拾") +
str.Substring(7);
case 9: return str.Substring(0, 1) + "億" +
DelZero(str.Substring(1, 1), "仟萬") +
DelZero(str.Substring(2, 1), "佰萬") +
DelZero(str.Substring(3, 1), "拾萬") +
DelZero(str.Substring(4, 1), "萬") +
DelZero(str.Substring(5, 1), "仟") +
DelZero(str.Substring(6, 1), "佰") +
DelZero(str.Substring(7, 1), "拾") +
str.Substring(8);
default: return "數字大於 999,999,999";
}
}
同樣輸入 60058905 經過第三步後會得到
ex: GetAnswer(int 60058905) => 陸仟萬零零伍萬捌仟玖佰零伍
Step 4: 對於『零零零...』的問題,只要再對字串做
ConvertLen2Dec(val2ch).Replace("零零零零零零零", "")
.Replace("零零零零零零", "零")
...;
類似的處理就能處理掉
所以完成 1~4 步後,輸入 60058905 會得到
ex: GetAnswer(int 60058905) => 陸仟萬零伍萬捌仟玖佰零伍
以下開始進入本篇主題
破萬時,如何解決『萬』重複的問題呢 ?
ex: 陸仟萬零伍萬
分析問題:
999990000 => 玖億玖仟萬玖佰萬玖拾萬玖萬 : 4個『萬』
正確值: 玖億玖仟玖佰玖拾玖萬
=> 『仟萬』變『仟』,『佰萬』變『佰』,『拾萬』變『拾』
999900000 => 玖億玖仟萬玖佰萬玖拾萬 : 3個『萬』
正確值: 玖億玖仟玖佰玖拾玖萬
=> 『仟萬』變『仟』,『佰萬』變『佰』
999000000 => 玖億玖仟萬玖佰萬 : 2個『萬』
正確值: 玖億玖仟玖佰萬 => 『仟萬』變『仟』
990000000 => 玖億玖仟萬 (正確值)
歸納結果:
當『萬』字有兩個以上時,就必須濾掉至 1 個,才能得到正確值
從歸納結果設計Step 5Step 5: 計數字串中『萬』的個數,如果個數超過 1 就將字串做『Replace("仟萬", "仟")...』處理
static string DelMuti10Thousand(string str) {
/*** 我們的 LinQ 在這裡 ***/
var query = from c in str.ToCharArray() where c == '萬' select c;
/************************/
if (query.Count() > 1)
return str.Replace("仟萬", "仟")
.Replace("佰萬", "佰")
.Replace("拾萬", "拾");
else
return str;
}
Language-Integrated Query(LinQ)有點類似 SparkSQL 提供我們使用一些熟悉的SQL語法來對
collection, List, (k, v)List, ...進行一些排序、擷取、分類、...操作。
只不過之前用 java 寫的 SparkSQL 應用必須在 Spark 環境下才能運作
var query = from c in str.ToCharArray() where c == '萬' select c;
這段是將 轉換成『字元陣列』中的『萬』字元撈出來變成一個新的集合
只要知道把撈出來的『萬』字元陣列做 Count() 計次,2次以上就
替換『仟萬』=> 『仟』,『佰萬』=> 『佰』,『拾萬』=> 『拾』
這題就解決了!
結論:
本篇的精神只是要分享 LinQ 的應用,並不是說一定要跟資料庫結合才能用。
wiki的說明:『...是微軟的一項技術,新增一種自然查詢的SQL語法到.NET Framework的程式語言中...』
反而會讓一些入門者誤會成只有在處理資料庫的情境下才會用到 LinQ。
本篇中舉例用 LinQ 來分析字串,並沒有與任何資料庫連結。